﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;

using SignalRService.Model;
using BartonExtension;

namespace SignalRService
{
    public class OPNotificationHub : Hub
    {
        public async Task Auth(string userName,string state)
        {
            string connectionId = Context.ConnectionId;
            OPUser user = OPUserCollection.shared.FindUser(u => u.userId == userName);
            if(user == null)
            {
                user = new OPUser();
                user.actionPing = (u,str,deleteflag) =>
                {
                    if (!deleteflag)
                        Clients.Clients(u.connections.ToList()).pulse(str);
                    else
                    {
                        OPUserCollection.shared.RemoveUser(u);
                    }
                };
                user.startPingPong();
                OPUserCollection.shared.AddUser(user);
            }
            user.AddConnection(connectionId);
            user.userId = userName;
            user.state = state;
            user.authorized = true;
            user.onlineStatus = UserOnlineStatus.kOnlineStatusOnline;
            await Clients.Caller.onAuthSuccess();
        }
        public void Pong(string userName)
        {
            string connectionId = Context.ConnectionId;
            OPUser user = OPUserCollection.shared.FindUser(u => u.userId == userName);
            if (user != null)
            {
               if(user.connections.Contains(connectionId))
               {
                   user.ResetPingPongCount(connectionId);
               }
               else
               {
                   user.AddConnection(connectionId);
               }
            }
        }
        public void MessageReceip(string messageid)
        {
            OPMessagePool.share.DeleteMessage(messageid);
        }
        public void GetOffline(string userId)
        {
            //Load offline data
            OPUser user = OPUserCollection.shared.FindUser(u => u.userId == userId);
            if (user != null)
            {
                List<OPMessage> messages = OPMessagePool.share.messagesByUser(userId);
                messages.ForEach(m =>
                {
                    Clients.Clients(user.connections.ToList()).broadcast(m.content).Wait();
                });
            }
        }
        public async Task Push(string context,string from,string to, PushContentType contentType)
        {
            PushContent notification = new PushContent()
            {
                messageid = Guid.NewGuid().ToString(),
                contentType = contentType,
                from = from,
                to = to,
                context = context,
                timetag = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            };
            
            if(contentType == PushContentType.kPushContentTypeBroadcast)
            {
                await Clients.All.broadcast(notification);
            }
            else if(contentType == PushContentType.kPushContentTypeP2P)
            {
                OPMessagePool.share.AddMessage(notification);
                OPUser user = OPUserCollection.shared.FindUser(u => u.userId == to);
                if(user != null)
                {
                    await Clients.Clients(user.connections.ToList()).broadcast(notification);
                }
                else
                {
                    OPIndexedUser u = OPUserCollection.shared.FindIndexedUser(k => k.userId == to);
                    if(u != null)
                        await Clients.Caller.userOffline(new List<object>() { u, notification });
                }
            }
            else if(contentType == PushContentType.kPushContentTypeTag)
            {

            }
        }
    }
}